package com.fuze.navi.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fuze.navi.common.Advice;
import com.fuze.navi.common.Constant;
import com.fuze.navi.common.NaviException;
import com.fuze.navi.common.Result;
import com.fuze.navi.domain.dto.UserDTO;
import com.fuze.navi.domain.model.User;
import com.fuze.navi.mapper.UserMapper;
import com.fuze.navi.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author sepc_
 * @date 3/16/2021 15:29
 */
@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserService {

    final UserMapper userMapper;

    final StringRedisTemplate stringRedisTemplate;

    @Override
    public Optional<User> getUserByAccount(String account) {
        LambdaQueryWrapper<User> qw = new QueryWrapper<User>()
                .lambda()
                .eq(User::getAccount, account);
        return Optional.ofNullable(userMapper.selectOne(qw));
    }

    @Override
    public void register(UserDTO userDTO) {
        String trimAccount = userDTO.getAccount().trim();
        LambdaQueryWrapper<User> qw = new QueryWrapper<User>()
                .lambda()
                .eq(User::getAccount, trimAccount);
        User user = userMapper.selectOne(qw);
        if (user != null) {
            throw new NaviException(Advice.REPEAT_REGISTRATION);
        }
        String trimPwd = userDTO.getPwd().trim();
        String salt = IdUtil.simpleUUID();
        user = new User();
        user.setAccount(trimAccount);
        user.setSalt(salt);
        user.setPwd(SecureUtil.md5(trimPwd + salt));
        int insert = userMapper.insert(user);
        if (insert != 1) {
            throw new NaviException(Advice.REGISTRATION_FAILED);
        }
    }

    @Override
    public boolean isExist(String account) {
        return userMapper.countByAccount(account);

    }

    @Override
    public void resetPwd(String userId, String newPwd) {
        String salt = IdUtil.simpleUUID();
        String md5Pwd = SecureUtil.md5(newPwd + salt);
        User user = userMapper.selectById(userId);
        user.setPwd(md5Pwd);
        user.setSalt(salt);
        int update = userMapper.updateById(user);
        if (update != 1) {
            throw new NaviException(Advice.PWD_RESET_FAILED);
        }
    }

    @Override
    public Optional<String> checkAccount(UserDTO user) {
        Optional<User> optional = this.getUserByAccount(user.getAccount().trim());
        if (optional.isPresent()) {
            User actualUser = optional.get();
            String pwd = actualUser.getPwd();
            String md5Pwd = SecureUtil.md5(user.getPwd().trim() + actualUser.getSalt());
            if (pwd.equals(md5Pwd)) {
                //密码匹配生成token
                String token = IdUtil.simpleUUID();
                String buffer = actualUser.getId() +
                        Constant.DELIMITER +
                        actualUser.getAccount() +
                        Constant.DELIMITER +
                        actualUser.getAuthority();
                stringRedisTemplate.opsForValue().set(token, buffer, 1L, TimeUnit.DAYS);
                return Optional.of(token);
            }
            throw new NaviException(Advice.WRONG_PASSWORD);
        }
        throw new NaviException(Advice.USER_NOT_EXIST);
    }
}
